﻿using System;
using System.Collections.Generic;
using System.Linq;
using AMM.DataAccess.Business;
using AMM.DataAccess.Store;
using AMM.Model;
using AMM.Model.PrintModels;

namespace AMM.Business {
    public class PrintDataSoruceHelper {

        private ProcurementOrderRepository _procurementOrderRepository;
        private SuspenseOrderRepository _suspenseOrderRepository;
        private QualityOrderRepository _qualityOrderRepository;
        private OutStoreOrderRepository _outStoreOrderRepository;
        private ProduceConductRepository _produceConductRepository;

        public PrintDataSoruceHelper() {
            this._procurementOrderRepository = new ProcurementOrderRepository();
            this._suspenseOrderRepository = new SuspenseOrderRepository();
            this._qualityOrderRepository = new QualityOrderRepository();
            this._outStoreOrderRepository = new OutStoreOrderRepository();
            this._produceConductRepository = new ProduceConductRepository();
        }

        #region Procurement order

        public List<PrintProcurementOrder> FetchPrintProcurementOrder(int procurementOrderId) {
            ProcurementOrder procurementOrder = this._procurementOrderRepository.FetchProcurementOrderById(procurementOrderId);
            List<PrintProcurementOrder> procurementOrderList = new List<PrintProcurementOrder>();
            procurementOrderList.Add(new PrintProcurementOrder() {
                Code = procurementOrder.Code,
                CreatedDatetime = procurementOrder.CreatedDatetime,
                VendorName = procurementOrder.Vendor.Name,
                VendorAddress = procurementOrder.Vendor.Address,
                VendorFax = procurementOrder.Vendor.Fax,
                VendorLinkman = procurementOrder.Vendor.Linkman
            });

            return procurementOrderList;
        }

        public List<PrintProcurementOrderDetails> FetchPrintProcurementOrderDetails(int procurementOrderId) {
            ProcurementOrder procurementOrder = this._procurementOrderRepository.FetchProcurementOrderByIdForView(procurementOrderId);
            return procurementOrder.ProcurementOrderDetails.Select(x => new PrintProcurementOrderDetails {
                MaterialCode = x.Material.Code,
                MaterialDescription = x.Material.Remarks,
                MaterialName = x.Material.Name,
                MaterialUnit = x.Material.Basic1.Code,
                DeliveryDate = x.DeliveryDate,
                Price = x.Price,
                Quantity = x.Quantity,
                Total = x.Total
            }).ToList();
        }

        #endregion

        #region Suspense order

        public List<PrintSuspenseOrder> FetchPrintSuspenseOrder(int suspenseOrderId) {
            SuspenseOrder suspenseOrder = this._suspenseOrderRepository.FetchSuspenseOrderById(suspenseOrderId);
            ProcurementOrder procurementOrder = this._procurementOrderRepository.FetchProcurementOrderById(suspenseOrder.ProcurementOrderId);
            List<PrintSuspenseOrder> suspenseOrderList = new List<PrintSuspenseOrder>();
            suspenseOrderList.Add(new PrintSuspenseOrder() {
                Code = suspenseOrder.Code,
                Author = suspenseOrder.CreatedBy,
                DeliveryCode = suspenseOrder.DeliveryOrderCode,
                PrintedDatetime = DateTime.Now,
                VendorName = procurementOrder.Vendor.Name
            });

            return suspenseOrderList;
        }

        public List<PrintSuspenseOrderDetails> FetchPrintSuspenseOrderDetails(int suspenseOrderId) {
            SuspenseOrder suspenseOrder = this._suspenseOrderRepository.FetchSuspenseOrderByIdForView(suspenseOrderId);
            ProcurementOrder procurementOrder = this._procurementOrderRepository.FetchProcurementOrderById(suspenseOrder.ProcurementOrderId);
            QualityOrder qualityOrder = this._qualityOrderRepository.FetchQualityOrderBySuspenseId(suspenseOrderId);
            return suspenseOrder.SuspenseOrderDetails.Select(x => new PrintSuspenseOrderDetails {
                MaterialCode = x.Material.Code,
                MaterialName = x.Material.Name,
                MaterialUnit = x.Material.Basic1.Code,
                ProcurementOrderCode = procurementOrder.Code,
                Quantity = x.SuspenseQuantity,
                QualifiedQuantity = qualityOrder == null
                    ? 0
                    : qualityOrder.QualityOrderDetails.FirstOrDefault(y => y.MaterialId == x.MaterialId).UnQualifiedQuantity,
                SuspenseDate = x.SuspenseDate
            }).ToList();
        }

        #endregion

        #region Out store order

        public List<PrintOutStoreOrder> FetchPrintOutStoreOrder(int outStoreOrderId) {
            OutStoreOrder outStoreOrder = this._outStoreOrderRepository.FetchOutStoreOrderById(outStoreOrderId);
            ProduceConduct produceConduct = this._produceConductRepository.FetchProduceConductByIdForPrint(outStoreOrder.ProduceConductId);
            List<PrintOutStoreOrder> outStoreOrderList = new List<PrintOutStoreOrder>();
            outStoreOrderList.Add(new PrintOutStoreOrder() {
                Code = outStoreOrder.Code,
                Author = outStoreOrder.CreatedBy,
                PrintedDatetime = DateTime.Now,
                BatchAmount = produceConduct.BatchAmount,
                OutStoreType = outStoreOrder.Basic.Name,
                ProduceConductCode = produceConduct.Code,
                ProductCode = produceConduct.Product.Code,
                ProductUnitCode = produceConduct.Product.Basic1.Code
            });

            return outStoreOrderList;
        }

        public List<PrintOutStoreOrderDetails> FetchPrintOutStoreOrderDetails(int outStoreOrderId) {
            OutStoreOrder outStoreOrder = this._outStoreOrderRepository.FetchOutStoreOrderByIdForView(outStoreOrderId);
            ProduceConduct produceConduct = this._produceConductRepository.FetchProduceConductByIdForPrint(outStoreOrder.ProduceConductId);
            List<BOMDetail> bomList = this._produceConductRepository.FetchProduceConductBOMMaterialList(outStoreOrder.ProduceConductId);

            List<PrintOutStoreOrderDetails> posodList = new List<PrintOutStoreOrderDetails>();
            outStoreOrder.OutStoreOrderDetails.ToList().ForEach(x => {
                PrintOutStoreOrderDetails posod = new PrintOutStoreOrderDetails() {
                    MaterialCode = x.Material.Code,
                    MaterialName = x.Material.Name,
                    MaterialUnit = x.Material.Basic1.Code,
                    OutStoreDate = x.CreatedDatetime,
                    Quantity = x.Quantity,
                    SingleUseQuantity = 0
                };
                if (bomList.Count > 0) {
                    posod.SingleUseQuantity = bomList.FirstOrDefault(y => y.MaterialId == x.MaterialId).SingleCosts;
                }
                posodList.Add(posod);
            });
            return posodList;
        }

        #endregion

        #region Produce conduct

        public List<PrintProduceConduct> FetchPrintProduceConduct(int produceConductId) {
            ProduceConduct produceConduct = this._produceConductRepository.FetchProduceConductByIdForPrint(produceConductId);
            List<PrintProduceConduct> produceConductList = new List<PrintProduceConduct>();
            produceConductList.Add(new PrintProduceConduct() {
                BatchAmount = produceConduct.BatchAmount,
                ProduceConductCode = produceConduct.Code,
                ProductCode = produceConduct.Product.Code,
                CreatedDatetime = produceConduct.OrderDate,
                CustomerOrderCode = produceConduct.CustomerOrder.OrderNo,
                ProductUnitCode = produceConduct.Product.Basic1.Code
            });

            return produceConductList;
        }

        public List<PrintProduceConductDetails> FetchPrintProduceConductDetails(int produceConductId) {
            ProduceConduct produceConduct = this._produceConductRepository.FetchProduceConductById(produceConductId);
            List<BOMDetail> bomList = this._produceConductRepository.FetchProduceConductBOMMaterialList(produceConductId);
            List<PrintProduceConductDetails> printProduceConductDetailList = new List<PrintProduceConductDetails>();
            bomList.ForEach(x => {
                printProduceConductDetailList.Add(new PrintProduceConductDetails() {
                    MaterialCode = x.Material.Code,
                    MaterialName = x.Material.Name,
                    SingleCosts = x.SingleCosts,
                    SourceCode = x.Basic.Code,
                    AmountCosts = x.SingleCosts * produceConduct.BatchAmount
                });
            });

            return printProduceConductDetailList;
        }

        #endregion
    }
}
